package org.tinycloud.tinyjob.client;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.env.Environment;
import org.tinycloud.tinyjob.client.interceptor.HostInvocationSecurityInterceptor;
import org.tinycloud.tinyjob.client.utils.LocalHostUtils;

import java.util.Collection;
import java.util.Objects;

/**
 * <p>
 * 执行器配置类-Spring
 * </p>
 *
 * @author liuxingyu01
 * @since 2025/10/13 22:09
 */
public class TinyJobExecutorSpringConfig extends TinyJobExecutorConfig implements ApplicationContextAware, SmartInitializingSingleton, DisposableBean, BeanDefinitionRegistryPostProcessor {
    private static final Logger logger = LoggerFactory.getLogger(TinyJobExecutorSpringConfig.class);

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        TinyJobExecutorSpringConfig.applicationContext = applicationContext;
    }

    /**
     * 获取Bean
     */
    public static <T> T getBean(Class<T> clazz) {
        T bean = null;
        Collection<T> beans = applicationContext.getBeansOfType(clazz).values();
        while (beans.iterator().hasNext()) {
            bean = beans.iterator().next();
            if (bean != null) {
                break;
            }
        }
        return bean;
    }

    /**
     * 初始化start（来自于SmartInitializingSingleton接口）
     */
    @Override
    public void afterSingletonsInstantiated() {
        try {
            logger.info("TinyJobExecutorSpringConfig start...");
            if (StringUtils.isNotBlank(this.getAdminAddresses()) && StringUtils.isNotBlank(this.getWorkerName()) && Objects.nonNull(this.getProjectId())) {
                if (this.getIp() == null || this.getIp().trim().isEmpty()) {
                    // 自动获取IP
                    this.setIp(LocalHostUtils.getLocalHost());
                }
                if (this.getPort() == null) {
                    // 自动获取端口
                    this.setPort(getBean(Environment.class).getProperty("server.port", Integer.class));
                }
                super.start();
                logger.info("TinyJobExecutorSpringConfig auto register success!");
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 关闭destroy（来自于DisposableBean接口）
     */
    @Override
    public void destroy() {
        logger.info("TinyJobExecutorSpringConfig destroy...");
        super.destroy();
    }


    /**
     * 手动注册 HostInvocationSecurityInterceptor 的 Bean 定义
     */
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(HostInvocationSecurityInterceptor.class);
        String beanName = "hostInvocationSecurityInterceptor";
        registry.registerBeanDefinition(beanName, builder.getBeanDefinition());
    }


    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        // 无需额外处理，保持默认
    }

}
